 
  

 






<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do;jsessionid=4FCCB481C702D708A7360133D128E359?Id=143 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:27:37 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
<head>
 <title>
  Java Practices -> Logging messages
 </title>
 <link rel="stylesheet" type="text/css" href="../stylesheet8.css" media="all">
 
 <link rel="shortcut icon" href='../images/favicon.ico' type="image/vnd.microsoft.icon">
 <meta name="description" content="Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples.">
 
 <meta name='keywords' content='Level,LogManager,log,logging,java,java programming,java practices,java idiom,java style,java design patterns,java coding conventions,'>
 
 
</head>
 
<body>


<div class='menu-bar'>
 
  <a href='../home/HomeAction.html' title='Table of Contents'>Home</a> |
  <a href='../vote/VoteSummaryAction-2.html' title='View Poll Results'>Poll</a> |
   
  <A href='../feedback/FeedbackAction451f-2.html?Operation=Show' title='Send Your Feedback'>Wiki</a> |
  <b><a href='../source/SourceAction-2.html' title='Grab Source Code'>Source Code</a></b><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |

  <a href='http://www.web4j.com/Java_Web_Application_Framework_Overview.jsp?From=1' title='Free Download - Java Web Application Framework'><b>WEB4J</b></a> |
  
  <a href='http://www.date4j.net/' title='Replacement for java.util.Date'><b>DATE4J</b></a> |

   <a href='../references/ReferencesAction-2.html' title='References'>Links</a>
   
  <form action='http://www.javapractices.com/search/SearchAction.do' method='get' class='search-form'>
   <input type='text' name='SearchTerms' value="" size=12 maxlength=50 class='search'>
   <input type='submit' value="Search">
  </form>
 
</div>

<P>



  

 






<p class="display-messages">

 

 

</p>


<div class="main-layout">
 
   

 




<div class='page-title'>Logging messages</div>

<div class='main-body'>
 
<br>Java's logging facility (see Sun's <a href="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html">overview</a>
and <a href="http://java.sun.com/javase/6/docs/api/java/util/logging/package-summary.html">API</a>
) has two parts : a configuration file, and an API for using logging services.
It is a good tool, and is perfectly fine for simple and moderate logging needs. 
(For <em>complex</em> logging needs, you might consider the <a href='http://logging.apache.org/log4j/docs/'>log4j</a> tool as an 
alternative.)

<P>Log entries can be sent to these destinations, as either simple text or as XML :
<ul>
<li>
the console</li>

<li>
a file</li>

<li>
a stream</li>

<li>
memory</li>

<li>
a TCP socket on a remote host</li>
</ul>
The <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/logging/Level.html">Level</a></tt>
class defines seven levels of logging enlightenment :
<ul>
<li>
<tt>FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE</tt></li>

<li>
<tt>ALL</tt> and <tt>OFF</tt> are defined values as well</li>
</ul>
Here is one style of using these <tt>Level</tt>s in code, which may be modified as desired :
<ul>
<li>
upon startup, use <tt>CONFIG</tt> to log configuration parameters</li>

<li>
during normal operation, use <tt>INFO</tt> to log high-level "heartbeat"
information</li>

<li>
when bugs or critical conditions occur, use <tt>SEVERE</tt></li>

<li>
debugging information might default to <tt>FINE</tt>, with <tt>FINER</tt> and <tt>FINEST</tt>
used occasionally, according to taste.</li>
</ul>
There is flexibility in how logging levels can be changed at runtime, without
the need for a restart :
<ul>
<li>
simply change the configuration file and call <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/logging/LogManager.html#readConfiguration()">LogManager.readConfiguration</a></tt>.</li>

<li>
or, change the level in the body of your code, using the logging API ;
for example, one might automatically increase the logging level in response
to unexpected events</li>
</ul>
Levels are attached to these items :
<ul>
<li>
an originating logging request (from a single line of code)</li>

<li>
a <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/logging/Logger.html">Logger</a></tt>
(usually attached to the package containing the above line of code)</li>

<li>
a <tt><a href="http://java.sun.com/javase/6/docs/api/java/util/logging/Handler.html">Handler</a></tt>
(attached to an application)</li>
</ul>
The flow of execution for a particular logging request usually proceeds
as follows :
<p><tt>logging request of some level is made to logger attached to current
package</tt>
<br><tt>if the request level is too low for that package's logger {</tt>
<br><tt>&nbsp;&nbsp; discard it</tt>
<br><tt>}</tt>
<br><tt>otherwise {</tt>
<br><tt>&nbsp;&nbsp; cycle through all handlers {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if the request level is too low
for that handler {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; discard it</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; otherwise {</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log the request</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</tt>
<br><tt>&nbsp;&nbsp; }</tt>
<br><tt>}</tt>
<p>Here is an example of a logging configuration file :
<p><tt># Properties file which configures the operation of the JDK</tt>
<br><tt># logging facility.</tt>
<p><tt># The system will look for this config file, first using</tt>
<br><tt># a System property specified at startup:</tt>
<br><tt>#</tt>
<br><tt># >java -Djava.util.logging.config.file=myLoggingConfigFilePath</tt>
<br><tt>#</tt>
<br><tt># If this property is not specified, then the config file is</tt>
<br><tt># retrieved from its default location at:</tt>
<br><tt>#</tt>
<br><tt># JDK_HOME/jre/lib/logging.properties</tt>
<p><tt># Global logging properties.</tt>
<br><tt># ------------------------------------------</tt>
<br><tt># The set of handlers to be loaded upon startup.</tt>
<br><tt># Comma-separated list of class names.</tt>
<br><tt># (? LogManager docs say no comma here, but JDK example has comma.)</tt>
<br><tt>handlers=java.util.logging.FileHandler, java.util.logging.ConsoleHandler</tt>
<p><tt># Default global logging level.</tt>
<br><tt># Loggers and Handlers may override this level</tt>
<br><tt>.level=INFO</tt>
<p><tt># Loggers</tt>
<br><tt># ------------------------------------------</tt>
<br><tt># Loggers are usually attached to packages.</tt>
<br><tt># Here, the level for each package is specified.</tt>
<br><tt># The global level is used by default, so levels</tt>
<br><tt># specified here simply act as an override.</tt>
<br><tt>myapp.ui.level=ALL</tt>
<br><tt>myapp.business.level=CONFIG</tt>
<br><tt>myapp.data.level=SEVERE</tt>
<p><tt># Handlers</tt>
<br><tt># -----------------------------------------</tt>
<p><tt># --- ConsoleHandler ---</tt>
<br><tt># Override of global logging level</tt>
<br><tt>java.util.logging.ConsoleHandler.level=SEVERE</tt>
<br><tt>java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter</tt>
<p><tt># --- FileHandler ---</tt>
<br><tt># Override of global logging level</tt>
<br><tt>java.util.logging.FileHandler.level=ALL</tt>
<p><tt># Naming style for the output file:</tt>
<br><tt># (The output file is placed in the directory</tt>
<br><tt># defined by the "user.home" System property.)</tt>
<br><tt>java.util.logging.FileHandler.pattern=%h/java%u.log</tt>
<p><tt># Limiting size of output file in bytes:</tt>
<br><tt>java.util.logging.FileHandler.limit=50000</tt>
<p><tt># Number of output files to cycle through, by appending an</tt>
<br><tt># integer to the base file name:</tt>
<br><tt>java.util.logging.FileHandler.count=1</tt>
<p><tt># Style of output (Simple or XML):</tt>
<br><tt>java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter</tt>
<p>An application should likely centralize the naming policy for <tt>Logger</tt>s,
since switching naming styles becomes a simple edit in one method, instead
of a large number of edits spread throughout the application. Reasons to
alter the naming policy might include :
<ul>
<li>
in a shared environment, adding an application name to the <tt>Logger</tt>
name can help distinguish one application's entries from others</li>

<li>
adding application version information might be beneficial for debugging</li>
</ul>

There is a common complaint with the JDK logging config file : a Handler cannot be 
restricted to a specific Logger. That is, Handlers defined in the config file are 
global, in the sense that they will be attached to <em>all</em> Loggers. This is 
particularly annoying in a server environment, since different applications will, 
by default, output logging statements into the same file.
<em>This behavior can be easily changed, but only by using the JDK logging API.</em>
Many would prefer to do this directly in the config file.

<P>Here is an example of using the logging API :
<br>
<PRE>

<span class='keyword'>package</span> myapp.business;

<span class='keyword'>import</span> java.util.logging.*;

<span class='comment'>/**
* Demonstrate Java's logging facilities, in conjunction
* with a logging config file.
*/</span>
<span class='keyword'>public</span> <span class='keyword'>final</span> <span class='keyword'>class</span> SimpleLogger {

  <span class='keyword'>public</span> <span class='keyword'>static</span> <span class='keyword'>void</span> main(String argv[]) {
    SimpleLogger thing = <span class='keyword'>new</span> SimpleLogger();
    thing.doSomething();
  }

  <span class='keyword'>public</span> <span class='keyword'>void</span> doSomething() {
    <span class='comment'>//Log messages, one for each level
</span>    <span class='comment'>//The actual logging output depends on the configured
</span>    <span class='comment'>//level for this package. Calls to "inapplicable"
</span>    <span class='comment'>//messages are inexpensive.
</span>    fLogger.finest(<span class='literal'>"this is finest"</span>);
    fLogger.finer(<span class='literal'>"this is finer"</span>);
    fLogger.fine(<span class='literal'>"this is fine"</span>);
    fLogger.config(<span class='literal'>"this is config"</span>);
    fLogger.info(<span class='literal'>"this is info"</span>);
    fLogger.warning(<span class='literal'>"this is a warning"</span>);
    fLogger.severe(<span class='literal'>"this is severe"</span>);

    <span class='comment'>//In the above style, the name of the class and
</span>    <span class='comment'>//method which has generated a message is placed
</span>    <span class='comment'>//in the output on a best-efforts basis only.
</span>    <span class='comment'>//To ensure that this information is always
</span>    <span class='comment'>//included, use the following "precise log"
</span>    <span class='comment'>//style instead :
</span>    fLogger.logp(Level.INFO, <span class='keyword'>this</span>.getClass().toString(), <span class='literal'>"doSomething"</span>, <span class='literal'>"blah"</span>);

    <span class='comment'>//For the very common task of logging exceptions, there is a
</span>    <span class='comment'>//method which takes a Throwable :
</span>    Throwable ex = <span class='keyword'>new</span> IllegalArgumentException(<span class='literal'>"Some exception text"</span>);
    fLogger.log(Level.SEVERE, <span class='literal'>"Some message"</span>, ex);

    <span class='comment'>//There are convenience methods for exiting and
</span>    <span class='comment'>//entering a method, which are at Level.FINER :
</span>    fLogger.exiting(<span class='keyword'>this</span>.getClass().toString(), <span class='literal'>"doSomething"</span>);

    <span class='comment'>//Display user.home directory, if desired.
</span>    <span class='comment'>//(This is the directory where the log files are generated.)
</span>    <span class='comment'>//System.out.println("user.home dir: " + System.getProperty("user.home") );
</span>  }

  <span class='comment'>// PRIVATE //
</span>
  <span class='comment'>//This logger will inherit the config of its parent, and add
</span>  <span class='comment'>//any further config as an override. A simple style is to use
</span>  <span class='comment'>//all config of the parent except, perhaps, for logging level.
</span>
  <span class='comment'>//This style uses a hard-coded literal and should likely be avoided:
</span>  <span class='comment'>//private static final Logger fLogger = Logger.getLogger("myapp.business");
</span>
  <span class='comment'>//This style has no hard-coded literals, but forces the logger
</span>  <span class='comment'>//to be non-static.
</span>  <span class='comment'>//private final Logger fLogger=Logger.getLogger(this.getClass().getPackage().getName());
</span>
  <span class='comment'>//This style uses a static field, but hard-codes a class literal.
</span>  <span class='comment'>//This is probably acceptable.
</span>  <span class='keyword'>private</span> <span class='keyword'>static</span> <span class='keyword'>final</span> Logger fLogger =
                     Logger.getLogger(SimpleLogger.<span class='keyword'>class</span>.getPackage().getName());
} 
</PRE>
<br>
<br>Example Run 1 , using the config file defined above :
<p><tt>>java -Djava.util.logging.config.file=C:\Temp\logging.properties</tt>
<br><tt>-cp . myapp.business.SimpleLogger</tt>
<p><tt>ConsoleHandler</tt> is configured to show only <tt>SEVERE</tt> messages
:
<p><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: this is severe</tt>
<br><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: Some message</tt>
<br><tt>java.lang.IllegalArgumentException: Some exception text</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at myapp.business.SimpleLogger.doSomething(SimpleLogger.java:39)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at myapp.business.SimpleLogger.main(SimpleLogger.java:13)</tt>
<p>While the <tt>FileHandler</tt> shows <tt>ALL</tt> that is sent to it
:
<p><tt>Jan 8, 2003 10:43:46 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>CONFIG: this is config</tt>
<br><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>INFO: this is info</tt>
<br><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>WARNING: this is a warning</tt>
<br><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: this is severe</tt>
<br><tt>Jan 8, 2003 10:43:47 AM class myapp.business.SimpleLogger doSomething</tt>
<br><tt>INFO: blah</tt>
<br><tt>Jan 8, 2003 10:43:47 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: Some message</tt>
<br><tt>java.lang.IllegalArgumentException: Some exception text</tt>
<br><tt>&nbsp;at myapp.business.SimpleLogger.doSomething(SimpleLogger.java:39)</tt>
<br><tt>&nbsp;at myapp.business.SimpleLogger.main(SimpleLogger.java:13)</tt>
<br>&nbsp;
<p>Example Run 2, showing the <tt>ConsoleHandler</tt> output, using the
<tt>logging.properties</tt>
file which ships with the JDK, and which logs only <tt>INFO</tt> level
and above :
<p><tt>>java -cp . myapp.business.SimpleLogger</tt>
<p><tt>Jan 8, 2003 10:52:31 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>INFO: this is info</tt>
<br><tt>Jan 8, 2003 10:52:31 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>WARNING: this is a warning</tt>
<br><tt>Jan 8, 2003 10:52:31 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: this is severe</tt>
<br><tt>Jan 8, 2003 10:52:31 AM class myapp.business.SimpleLogger doSomething</tt>
<br><tt>INFO: blah</tt>
<br><tt>Jan 8, 2003 10:52:31 AM myapp.business.SimpleLogger doSomething</tt>
<br><tt>SEVERE: Some message</tt>
<br><tt>java.lang.IllegalArgumentException: Some exception text</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at myapp.business.SimpleLogger.doSomething(SimpleLogger.java:39)</tt>
<br><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; at myapp.business.SimpleLogger.main(SimpleLogger.java:13)</tt>
<br>
<br>

</div>





<div class='topic-section'>Would you use this technique?</div>
<div class='main-body'>
  
  <form action="http://www.javapractices.com/vote/AddVoteAction.do" method='post'>
    Yes<input type='radio' name='Choice' value='Y' >
    &nbsp;&nbsp;No<input type='radio' name='Choice' value='N'>
    &nbsp;&nbsp;Undecided<input type='radio' name='Choice' value="?" >
    &nbsp;&nbsp;<input type=submit value="Vote" >
    <input type='hidden' name='Operation' value='Apply'>
    <input type='hidden' name='TopicId' value='143'>
  </form>
</div>

<div style='height:10.0em;'></div>

 
 
</div>

  

 





<div align='center' class='legalese'>  
&copy; 2011 Hirondelle Systems |
<a href='../source/SourceAction-2.html'><b>Source Code</b></a><IMG class='no-margin' SRC="../images/goldstar.gif" ALT=""> |
<a href="mailto:webmaster@javapractices.com">Contact</a> |
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/">License</a> |
<a href='../apps/cjp.rss'>RSS</a>
<!-- ukey="2AC36CD2" -->
<!-- ckey="16DF3D87" -->
<br>

 Individual code snippets can be used under this <a href='../LICENSE.txt'>BSD license</a> - Last updated on June 6, 2010.<br>
 Over 150,000 unique IPs last month - <span title='Java Practices 2.6.5, Mon May 16 00:00:00 EDT 2011'>Built with</span> <a href='http://www.web4j.com/'>WEB4J</a>.<br>
 - In Memoriam : Bill Dirani -
</div>

<script src="../../www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-2633428-1";
urchinTracker();
</script>



</body>

<!-- Mirrored from www.javapractices.com/topic/TopicAction.do;jsessionid=4FCCB481C702D708A7360133D128E359?Id=143 by HTTrack Website Copier/3.x [XR&CO'2010], Sun, 12 Jun 2011 17:27:37 GMT -->
<!-- Added by HTTrack --><meta http-equiv="content-type" content="text/html;charset=UTF-8"><!-- /Added by HTTrack -->
</html>
